{
 "cells": [
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "# Day10 正则中常见的`\\`开头特殊序列的用法"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "　　我们在之前的日程中介绍过`\\`可以对**正则表达式**中的元字符进行转义，从而匹配到元字符所代表的原始字符串，而除了类作用外，`\\`还可以衔接一些特殊的字母，从而起到很多特殊作用，今天的日程里就将列举一些常见的`\\`开头特殊模式的用法。"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "- **\\s与\\S**\n",
    "\n",
    "　　`\\s`用于概括包括`\\n`（换行）、`\\t`（制表符）等在内的**unicode空白符**，即字符串在被打印后看起来是空白的区域，譬如下面的字符串："
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 1,
   "metadata": {
    "execution": {
     "iopub.execute_input": "2020-09-05T06:11:53.288497Z",
     "iopub.status.busy": "2020-09-05T06:11:53.287501Z",
     "iopub.status.idle": "2020-09-05T06:11:53.298475Z",
     "shell.execute_reply": "2020-09-05T06:11:53.297472Z",
     "shell.execute_reply.started": "2020-09-05T06:11:53.288497Z"
    }
   },
   "outputs": [
    {
     "name": "stdout",
     "output_type": "stream",
     "text": [
      "a\tb\tc\td\n",
      "e\tf\tg\th\n"
     ]
    }
   ],
   "source": [
    "import re\n",
    "\n",
    "s = 'a\\tb\\tc\\td\\ne\\tf\\tg\\th'\n",
    "print(s)"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "　　这类字符串的特点就是打印出来之后只能看到或长或短的空白或换行，要使用正则捕获这一类字符，就可以使用到`\\s`："
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 2,
   "metadata": {
    "execution": {
     "iopub.execute_input": "2020-09-05T06:11:53.300464Z",
     "iopub.status.busy": "2020-09-05T06:11:53.299466Z",
     "iopub.status.idle": "2020-09-05T06:11:53.321408Z",
     "shell.execute_reply": "2020-09-05T06:11:53.320412Z",
     "shell.execute_reply.started": "2020-09-05T06:11:53.300464Z"
    }
   },
   "outputs": [
    {
     "data": {
      "text/plain": [
       "['\\t', '\\t', '\\t', '\\n', '\\t', '\\t', '\\t']"
      ]
     },
     "execution_count": 2,
     "metadata": {},
     "output_type": "execute_result"
    }
   ],
   "source": [
    "re.findall('\\s+', s)"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "　　而`\\S`的意义则相当于对`\\s`取反，即匹配所有非**unicode空白字符**："
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 3,
   "metadata": {
    "execution": {
     "iopub.execute_input": "2020-09-05T06:11:53.324400Z",
     "iopub.status.busy": "2020-09-05T06:11:53.323403Z",
     "iopub.status.idle": "2020-09-05T06:11:53.337366Z",
     "shell.execute_reply": "2020-09-05T06:11:53.335387Z",
     "shell.execute_reply.started": "2020-09-05T06:11:53.324400Z"
    }
   },
   "outputs": [
    {
     "data": {
      "text/plain": [
       "['a', 'b', 'c', 'd', 'e', 'f', 'g', 'h']"
      ]
     },
     "execution_count": 3,
     "metadata": {},
     "output_type": "execute_result"
    }
   ],
   "source": [
    "re.findall('\\S+', s)"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "- **\\d与\\D**\n",
    "\n",
    "　　`\\d`用于表示任意10进制数字，等价于`[0-9]`："
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 4,
   "metadata": {
    "execution": {
     "iopub.execute_input": "2020-09-05T06:11:53.339361Z",
     "iopub.status.busy": "2020-09-05T06:11:53.338363Z",
     "iopub.status.idle": "2020-09-05T06:11:53.352327Z",
     "shell.execute_reply": "2020-09-05T06:11:53.350331Z",
     "shell.execute_reply.started": "2020-09-05T06:11:53.339361Z"
    }
   },
   "outputs": [
    {
     "data": {
      "text/plain": [
       "['21312', '21312', '321312']"
      ]
     },
     "execution_count": 4,
     "metadata": {},
     "output_type": "execute_result"
    }
   ],
   "source": [
    "s = '21312hghgf21312ghhhg321312'\n",
    "\n",
    "re.findall('\\d+', s)"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "　　`\\D`则与`\\d`意义相反，它代表除了数字外的所有其他字符，等价于`[^0-9]`："
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 5,
   "metadata": {
    "execution": {
     "iopub.execute_input": "2020-09-05T06:11:53.354321Z",
     "iopub.status.busy": "2020-09-05T06:11:53.353324Z",
     "iopub.status.idle": "2020-09-05T06:11:53.368284Z",
     "shell.execute_reply": "2020-09-05T06:11:53.367285Z",
     "shell.execute_reply.started": "2020-09-05T06:11:53.354321Z"
    }
   },
   "outputs": [
    {
     "data": {
      "text/plain": [
       "['hghgf', 'ghhhg']"
      ]
     },
     "execution_count": 5,
     "metadata": {},
     "output_type": "execute_result"
    }
   ],
   "source": [
    "re.findall('\\D+', s)"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "- **\\w与\\W**\n",
    "\n",
    "　　`\\w`代表着常规的组成词语（单词、汉字等）的**unicode字符**，默认状态下也包括了数字与下划线，类似`Python`的变量命名规则中对变量名合法性的定义："
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 6,
   "metadata": {
    "execution": {
     "iopub.execute_input": "2020-09-05T06:11:53.371275Z",
     "iopub.status.busy": "2020-09-05T06:11:53.370279Z",
     "iopub.status.idle": "2020-09-05T06:11:53.390224Z",
     "shell.execute_reply": "2020-09-05T06:11:53.389227Z",
     "shell.execute_reply.started": "2020-09-05T06:11:53.371275Z"
    }
   },
   "outputs": [
    {
     "data": {
      "text/plain": [
       "['今天',\n",
       " '是个好日子',\n",
       " 'today',\n",
       " 'is',\n",
       " 'a',\n",
       " 'good',\n",
       " 'day',\n",
       " '今日はいい日だ',\n",
       " '오늘은',\n",
       " '좋은',\n",
       " '날이다',\n",
       " 'Aujourd',\n",
       " 'hui',\n",
       " 'est',\n",
       " 'un',\n",
       " 'bon',\n",
       " 'jour',\n",
       " 'Ein',\n",
       " 'guter',\n",
       " 'tag',\n",
       " 'Хороший',\n",
       " 'день']"
      ]
     },
     "execution_count": 6,
     "metadata": {},
     "output_type": "execute_result"
    }
   ],
   "source": [
    "s = '今天，是个好日子，today is a good day，今日はいい日だ，오늘은 좋은 날이다，Aujourd’hui est un bon jour，Ein guter tag，Хороший день.'\n",
    "re.findall('\\w+', s)"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "　　可以看到常见各种语言的文字都属于`\\w`的范畴，而`\\W`则与`\\w`要表达的意义相反："
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 7,
   "metadata": {
    "execution": {
     "iopub.execute_input": "2020-09-05T06:11:53.392219Z",
     "iopub.status.busy": "2020-09-05T06:11:53.391221Z",
     "iopub.status.idle": "2020-09-05T06:11:53.406181Z",
     "shell.execute_reply": "2020-09-05T06:11:53.405183Z",
     "shell.execute_reply.started": "2020-09-05T06:11:53.392219Z"
    }
   },
   "outputs": [
    {
     "data": {
      "text/plain": [
       "['，',\n",
       " '，',\n",
       " ' ',\n",
       " ' ',\n",
       " ' ',\n",
       " ' ',\n",
       " '，',\n",
       " '，',\n",
       " ' ',\n",
       " ' ',\n",
       " '，',\n",
       " '’',\n",
       " ' ',\n",
       " ' ',\n",
       " ' ',\n",
       " ' ',\n",
       " '，',\n",
       " ' ',\n",
       " ' ',\n",
       " '，',\n",
       " ' ',\n",
       " '.']"
      ]
     },
     "execution_count": 7,
     "metadata": {},
     "output_type": "execute_result"
    }
   ],
   "source": [
    "re.findall('\\W+', s)"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "- **补充：对汉字的匹配**\n",
    "\n",
    "　　前面虽然我们发现了`\\w`可以匹配语言中的词汇内容，但是不分国籍统统给匹配到了，如果我们真正需要的是原始字符串中的**汉字**内容，譬如制作词云图之前的数据清洗过程，我们就可以使用到常见汉字在**unicode编码**中的范围`\\u4e00到\\u9fa5`，这囊括了常见的20902个汉字："
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 7,
   "metadata": {
    "execution": {
     "iopub.execute_input": "2020-09-05T06:11:53.407179Z",
     "iopub.status.busy": "2020-09-05T06:11:53.407179Z",
     "iopub.status.idle": "2020-09-05T06:11:53.427126Z",
     "shell.execute_reply": "2020-09-05T06:11:53.426128Z",
     "shell.execute_reply.started": "2020-09-05T06:11:53.407179Z"
    }
   },
   "outputs": [
    {
     "data": {
      "text/plain": [
       "['观察者网讯',\n",
       " '美国政府对中国科技企业',\n",
       " '卡脖子',\n",
       " '如今盯上了中芯国际',\n",
       " '路透社',\n",
       " '月',\n",
       " '日援引消息人士称',\n",
       " '特朗普政府正考虑是否将中国最大的芯片制造商中芯国际',\n",
       " '加入',\n",
       " '实体清单']"
      ]
     },
     "execution_count": 7,
     "metadata": {},
     "output_type": "execute_result"
    }
   ],
   "source": [
    "s = '观察者网讯）美国政府对中国科技企业“卡脖子”，如今盯上了中芯国际。路透社9月4日援引消息人士称，特朗普政府正考虑是否将中国最大的芯片制造商中芯国际（SMIC）加入“实体清单”。'\n",
    "\n",
    "re.findall('[\\u4e00-\\u9fa5]+', s)"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "### Day10 课后小测验\n",
    "\n",
    "　　通过今天的内容我们学习到了这么多的特殊模式，下面请你从目标字符串中匹配所有**5字**及以上的且不以**年**和**天**结尾的成语："
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 8,
   "metadata": {
    "execution": {
     "iopub.execute_input": "2020-09-05T06:11:53.430117Z",
     "iopub.status.busy": "2020-09-05T06:11:53.429120Z",
     "iopub.status.idle": "2020-09-05T06:11:53.441087Z",
     "shell.execute_reply": "2020-09-05T06:11:53.440090Z",
     "shell.execute_reply.started": "2020-09-05T06:11:53.430117Z"
    }
   },
   "outputs": [],
   "source": [
    "target = '一物降一物、过眼云烟、勾心斗角、富贵不能淫、水至清则无鱼、九牛一毛、Absence makes the heart grow fonder.欲速则不达、巧妇难为无米之炊、民以食为天、君子之交淡如水、枯木逢春、鲤鱼跳龙门、志同道合、No cross, no crown.十八般武艺、二一添作五、East or west, home is best.饱暖思淫欲、瑞雪兆丰年、五十步笑百步'"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 29,
   "metadata": {},
   "outputs": [
    {
     "data": {
      "text/plain": [
       "['一物降一物',\n",
       " '富贵不能淫',\n",
       " '水至清则无鱼',\n",
       " '欲速则不达',\n",
       " '巧妇难为无米之炊',\n",
       " '君子之交淡如水',\n",
       " '鲤鱼跳龙门',\n",
       " '十八般武艺',\n",
       " '二一添作五',\n",
       " '饱暖思淫欲',\n",
       " '五十步笑百步']"
      ]
     },
     "execution_count": 29,
     "metadata": {},
     "output_type": "execute_result"
    }
   ],
   "source": [
    "re.findall('[\\u4e00-\\u9fa5]{4,}[^年天、]',target)"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {
    "execution": {
     "iopub.execute_input": "2020-08-26T12:55:19.898241Z",
     "iopub.status.busy": "2020-08-26T12:55:19.897245Z",
     "iopub.status.idle": "2020-08-26T12:55:19.904225Z",
     "shell.execute_reply": "2020-08-26T12:55:19.903227Z",
     "shell.execute_reply.started": "2020-08-26T12:55:19.898241Z"
    }
   },
   "source": [
    "　　请将你的答案截图发到本帖评论区~"
   ]
  }
 ],
 "metadata": {
  "kernelspec": {
   "display_name": "Python 3",
   "language": "python",
   "name": "python3"
  },
  "language_info": {
   "codemirror_mode": {
    "name": "ipython",
    "version": 3
   },
   "file_extension": ".py",
   "mimetype": "text/x-python",
   "name": "python",
   "nbconvert_exporter": "python",
   "pygments_lexer": "ipython3",
   "version": "3.6.1"
  },
  "widgets": {
   "application/vnd.jupyter.widget-state+json": {
    "state": {},
    "version_major": 2,
    "version_minor": 0
   }
  }
 },
 "nbformat": 4,
 "nbformat_minor": 4
}
